<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 
<html>
<head>
<title>Cairo backends</title>
<link rel="stylesheet" href="/cfg/format.css" type="text/css">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="keywords" content="cairo, graphics, C, 2D vector library, backends">
<meta name="description" content="In this part of the Cairo graphics tutorial, we will
cover the Cairo backends.">
<meta name="language" content="en">
<meta name="author" content="Jan Bodnar">
<meta name="distribution" content="global">

<script type="text/javascript" src="/lib/jquery.js"></script>
<script type="text/javascript" src="/lib/common.js"></script>

</head>

<body>

<div class="container">

<div id="wide_ad" class="ltow">
<script type="text/javascript"><!--
google_ad_client = "pub-9706709751191532";
/* 160x600, August 2011 */
google_ad_slot = "2484182563";
google_ad_width = 160;
google_ad_height = 600;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>

<div class="content">


<a href="/" title="Home">Home</a>&nbsp;
<a href="..">Contents</a>


<h1>Cairo backends</h1>


<p>
The Cairo library supports various backends. In this section of the Cairo 
graphics tutorial, we will use Cairo to create a PNG image, PDF file, 
SVG file and we will draw on a GTK window.
</p>

<script type="text/javascript"><!--
google_ad_client = "pub-9706709751191532";
/* NewSquare */
google_ad_slot = "0364418177";
google_ad_width = 300;
google_ad_height = 250;
//-->
</script> 
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> 
</script>


<h2>PNG image</h2>

<p>
In the first example, we will create a PNG image.
</p>

<pre class="code">
#include &lt;cairo.h&gt;

int main(void)
{
  cairo_surface_t *surface;
  cairo_t *cr;

  surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 390, 60);
  cr = cairo_create(surface);

  cairo_set_source_rgb(cr, 0, 0, 0);
  cairo_select_font_face(cr, "Sans", CAIRO_FONT_SLANT_NORMAL,
      CAIRO_FONT_WEIGHT_NORMAL);
  cairo_set_font_size(cr, 40.0);

  cairo_move_to(cr, 10.0, 50.0);
  cairo_show_text(cr, "Disziplin ist Macht.");

  cairo_surface_write_to_png(surface, "image.png");

  cairo_destroy(cr);
  cairo_surface_destroy(surface);

  return 0;
}
</pre>

<p>
This example is a small console application, that will create a PNG image.
</p>

<pre class="explanation">
#include &lt;cairo.h&gt;
</pre>

<p>
In this header file, we will find declarations of our functions and constants.
</p>

<pre class="explanation">
cairo_surface_t *surface;
cairo_t *cr;
</pre>

<p>
Here we declare a surface and a Cairo context.
</p>

<pre class="explanation">
surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 390, 60);
cr = cairo_create(surface);
</pre>

<p>
We create a surface and a Cairo context. The surface is an 390x60 px image.
</p>

<pre class="explanation">
cairo_set_source_rgb(cr, 0, 0, 0);
</pre>

<p>
We will draw in black ink.
</p>


<pre class="explanation">
cairo_select_font_face(cr, "Sans", CAIRO_FONT_SLANT_NORMAL,
    CAIRO_FONT_WEIGHT_NORMAL);
cairo_set_font_size(cr, 40.0);
</pre>

<p>
We choose a font type and set its size.
</p>

<pre class="explanation">
cairo_move_to(cr, 10.0, 50.0);
cairo_show_text(cr, "Disziplin ist Macht.");
</pre>

<p>
We move to a (10.0, 50.0) position within the image and draw the text. 
</p>

<pre class="explanation">
cairo_surface_write_to_png(surface, "image.png");
</pre>

<p>
This function call creates the PNG image.
</p>

<pre class="explanation">
cairo_destroy(cr);
cairo_surface_destroy(surface);
</pre>

<p>
In the end, we clean the resources.
</p>


<h2>PDF file</h2>

<p>
In the second example, we will use the Cairo library to create a simple PDF file.
</p>

<pre class="code">
#include &lt;cairo.h&gt;
#include &lt;cairo-pdf.h&gt;

int main(void) 
{
  cairo_surface_t *surface;
  cairo_t *cr;

  surface = cairo_pdf_surface_create("pdffile.pdf", 504, 648);
  cr = cairo_create(surface);

  cairo_set_source_rgb(cr, 0, 0, 0);
  cairo_select_font_face (cr, "Sans", CAIRO_FONT_SLANT_NORMAL,
      CAIRO_FONT_WEIGHT_NORMAL);
  cairo_set_font_size (cr, 40.0);

  cairo_move_to(cr, 10.0, 50.0);
  cairo_show_text(cr, "Disziplin ist Macht.");

  cairo_show_page(cr);

  cairo_surface_destroy(surface);
  cairo_destroy(cr);

  return 0;
}
</pre>

<p>
We must open the pdf file in a pdf viewer. Linux users can use KPDF or Evince viewers.
</p>

<pre class="explanation">
surface = cairo_pdf_surface_create("pdffile.pdf", 504, 648);
</pre>

<p>
To render a pdf file, we must create a pdf surface using the 
<code>cairo_pdf_surface_create()</code> function call.
The size of the pdf file is specified in points, which is a standard in typesetting. 
</p>

<pre class="explanation">
cairo_show_page(cr);
</pre>

<p>
The <code>cairo_show_page()</code> finishes rendering of the pdf file.
</p>

<img src="/img/gfx/cairoc/pdffile.png" alt="PDF file in Evince">
<div class="figure">Figure: PDF file in Evince</div>


<h2>SVG file</h2>

<p>
The next example creates a simple SVG (Scalable Vector Graphics) file. 
The SVG is one of the hottest 
technologies these days.
</p>

<pre class="code">
#include &lt;cairo.h&gt;
#include &lt;cairo-svg.h&gt; 
 
int main(void) 
{
  cairo_surface_t *surface;
  cairo_t *cr;

  surface = cairo_svg_surface_create("svgfile.svg", 390, 60);
  cr = cairo_create(surface);

  cairo_set_source_rgb(cr, 0, 0, 0);
  cairo_select_font_face(cr, "Sans", CAIRO_FONT_SLANT_NORMAL,
      CAIRO_FONT_WEIGHT_NORMAL);
  cairo_set_font_size(cr, 40.0);

  cairo_move_to(cr, 10.0, 50.0);
  cairo_show_text(cr, "Disziplin ist Macht.");

  cairo_surface_destroy(surface);
  cairo_destroy(cr);

  return 0;
}
</pre>

<p>
We can use Firefox, Opera or Inkscape programs to open the svgfile.svg file. 
</p>

<pre class="explanation">
surface = cairo_svg_surface_create("svgfile.svg", 390, 60);
</pre>

<p>
To create a SVG file in Cairo, we must create a svg surface using the 
<code>cairo_svg_surface_create()</code> function call.
</p>

<pre class="explanation">
cr = cairo_create(surface);
</pre>

<p>
A Cairo context is created from a SVG surface.
</p>

<p>
The Rest of the code is identical to the previous examples.
</p>

<img src="/img/gfx/cairoc/svgfile.jpg" alt="SVG file in Chrome">
<div class="figure">SVG file in Chrome</div>


<h2>GTK Window</h2>

<p>
In the last example, we will draw on the GTK window. This backend will be used 
throughout the rest of the tutorial.
</p>

<pre class="code">
#include &lt;cairo.h&gt;
#include &lt;gtk/gtk.h&gt;

static void do_drawing(cairo_t *);

static gboolean on_draw_event(GtkWidget *widget, cairo_t *cr, 
    gpointer user_data)
{      
  cr = gdk_cairo_create(gtk_widget_get_window(widget));
  do_drawing(cr);
  cairo_destroy(cr);

  return FALSE;
}

static void do_drawing(cairo_t *cr)
{
  cairo_set_source_rgb(cr, 0, 0, 0);
  cairo_select_font_face(cr, "Sans", CAIRO_FONT_SLANT_NORMAL,
      CAIRO_FONT_WEIGHT_NORMAL);
  cairo_set_font_size(cr, 40.0);

  cairo_move_to(cr, 10.0, 50.0);
  cairo_show_text(cr, "Disziplin ist Macht.");    
}


int main(int argc, char *argv[])
{
  GtkWidget *window;
  GtkWidget *darea;

  gtk_init(&amp;argc, &amp;argv);

  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

  darea = gtk_drawing_area_new();
  gtk_container_add(GTK_CONTAINER(window), darea);

  g_signal_connect(G_OBJECT(darea), "draw", 
      G_CALLBACK(on_draw_event), NULL); 
  g_signal_connect(window, "destroy",
      G_CALLBACK(gtk_main_quit), NULL);

  gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
  gtk_window_set_default_size(GTK_WINDOW(window), 400, 90); 
  gtk_window_set_title(GTK_WINDOW(window), "GTK window");

  gtk_widget_show_all(window);

  gtk_main();

  return 0;
}
</pre>

<p>
The example pops up a centered GTK window, on which we draw the 
"Disziplin ist Macht" text.
</p>

<pre class="explanation">
#include &lt;cairo.h&gt;
#include &lt;gtk/gtk.h&gt;
</pre>

<p>
We include the necessary Cairo and GTK headers.
</p>

<pre class="explanation">
static gboolean on_draw_event(GtkWidget *widget, cairo_t *cr, 
    gpointer user_data)
{      
  cr = gdk_cairo_create(gtk_widget_get_window(widget));
  do_drawing(cr);
  cairo_destroy(cr);

  return FALSE;
}
</pre>

<p>
In the on_draw_event() function, we create a Cairo context. It is
a graphics object on which we perform the drawing operations. Actual
drawing is delegated to the do_drawing() function. After the drawing,
the cairo context is destroyed. 
</p>

<pre class="explanation">
static void do_drawing(cairo_t *cr)
{
  cairo_set_source_rgb(cr, 0, 0, 0);
  cairo_select_font_face(cr, "Sans", CAIRO_FONT_SLANT_NORMAL,
      CAIRO_FONT_WEIGHT_NORMAL);
  cairo_set_font_size(cr, 40.0);

  cairo_move_to(cr, 10.0, 50.0);
  cairo_show_text(cr, "Disziplin ist Macht.");    
}
</pre>

<p>
The drawing is done in the do_drawing() function.
</p>


<pre class="explanation">
darea = gtk_drawing_area_new();
gtk_container_add(GTK_CONTAINER(window), darea);
</pre>

<p>
We create a GtkDrawingArea widget and add it to the container window. It is
used for custom drawing. 
</p>

<pre class="explanation">
g_signal_connect(G_OBJECT(darea), "draw", 
    G_CALLBACK(on_draw_event), NULL); 
</pre>

<p>
When the GtkDrawingArea widget needs to be redrawn, it emits the  <code>draw</code> signal.
We connect that signal to the <code>on_draw_event()</code> callback.
</p>

<img src="/img/gfx/cairoc/window.png" alt="GTK window">
<div class="figure">Figure: GTK window</div>


<p>
In this chapter we have covered supported Cairo backends.
</p>

<div class="center"> 
<script type="text/javascript"><!--
google_ad_client = "pub-9706709751191532";
/* horizontal */
google_ad_slot = "1734478269";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script> 
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> 
</script> 
</div>
<br>



<div class="botNav, center">
<span class="botNavItem"><a href="/">Home</a></span> ‡ <span class="botNavItem"><a href="..">Contents</a></span> ‡ 
<span class="botNavItem"><a href="#">Top of Page</a></span>
</div>


<div class="footer">
<div class="signature">
<a href="/">ZetCode</a> last modified December 12, 2012  <span class="copyright">&copy; 2007 - 2013 Jan Bodnar</span>
</div>
</div>

</div> <!-- content -->

</div> <!-- container -->

</body>
</html>


